extends Reference
class_name CellType

const SIGNAL_COUNT = 10 #needs to be more than 2

var MUTATION_RATE_MATRIX = 0.1
var MUTATION_RATE_PRODUCTION = 0.1
var MUTATION_RATE_PROLIFERATION = 0.3

var FIELD_CAP = 1
var MATRIX_CAP = 10

var color

enum types {
	ROOM,
	CORRIDOR,
}

var type_index = types.ROOM

var matrix = []
var own_production = []
var proliferations = []

class Proliferation:
	var min_ranges = []
	var max_ranges = []

	func _init():
		for i in range(SIGNAL_COUNT):
			min_ranges.append(0)
			max_ranges.append(0)


func _init():
	randomize()
	for i in range(SIGNAL_COUNT):
		matrix.append([])
		for j in range(SIGNAL_COUNT):
			matrix[i].append(0.0)

	for i in range(SIGNAL_COUNT):
		own_production.append(0)

	for t in types:
		proliferations.append(Proliferation.new())

func mix(field_vector): # uncapped because is not final
	assert(field_vector.size() == SIGNAL_COUNT)

	var ret = []
	for i in range(SIGNAL_COUNT):
		ret.append(0)

	for i in range(SIGNAL_COUNT):
		var response_sum = 0

		for j in range(SIGNAL_COUNT):
			response_sum += matrix[i][j] * field_vector [j]
		ret[i] = response_sum

	#print ("mix: returning \n", ret)

	return ret

func mutate(gentle_divisor = 1.0):
	var ret = load("res://CellType.gd").new()
	for i in range(SIGNAL_COUNT):
		for j in range(SIGNAL_COUNT):
				ret.matrix[i][j] = clamp( matrix[i][j] + MUTATION_RATE_MATRIX * ((randf()-0.5)*2) / gentle_divisor,
				-MATRIX_CAP,MATRIX_CAP)

	for i in range(SIGNAL_COUNT):
		ret.own_production[i] = own_production[i] + MUTATION_RATE_PRODUCTION * ((randf()-0.5)*2)/(gentle_divisor)
		#print ("mutator: preproduction \n",ret.own_production)
		ret.own_production[i] = clamp(ret.own_production[i],-FIELD_CAP,FIELD_CAP)

	for i in range(types.size()):
		var p = ret.proliferations[i]
		var parent_p = proliferations[i]

		for j in range(SIGNAL_COUNT):

			p.min_ranges[j] = parent_p.min_ranges[j] + (randf()-0.5)*2.0*MUTATION_RATE_PROLIFERATION/(gentle_divisor)
			p.min_ranges[j] = clamp(p.min_ranges[j], -FIELD_CAP, parent_p.max_ranges[j])
			p.max_ranges[j] = parent_p.max_ranges[j] + (randf()-0.5)*2.0*MUTATION_RATE_PROLIFERATION/(gentle_divisor)
			p.max_ranges[j] = clamp(p.max_ranges[j], parent_p.min_ranges[j], FIELD_CAP)

	ret.type_index = type_index
	#print ("mutator: returning production \n",ret.own_production)
	return ret
